package geektime.concurrent.part1;

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

/**
 * 验证ArrayList在多线程中的不安全性
 */
public class ArrayListInThread implements Runnable {
//    List<String> testList = new ArrayList<>();
    // CopyOnWriteArrayList是线程安全的。
    // 当容器中需要添加或删除元素时，会先copy一个副本容器来进行操作，操作结束后将原来的引用指向新的副本容器
//    List<String> testList = new CopyOnWriteArrayList<>();
    // 通过Collections.synchronizedList()包装集合后，也可以做到线程安全
    List<String> testList = Collections.synchronizedList(new ArrayList<>());

    @Override
    public void run() {
        try {
            Thread.sleep((int)(Math.random() * 2));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        testList.add(Thread.currentThread().getName());
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadGroup threadGroup = new ThreadGroup("testGroup");
        ArrayListInThread arrayListInThread = new ArrayListInThread();
        for (int i = 0; i < 100000; i++) {
            Thread thread = new Thread(threadGroup, arrayListInThread, String.valueOf(i));
            thread.start();
        }
        // 确保所有的线程都已经执行完毕
        while (threadGroup.activeCount() > 0) {
            Thread.sleep(10);
        }
        System.out.println(arrayListInThread.testList.size());
    }
}
